import { director } from 'cc';
import { BundleManager } from './BundleManager';
import { SceneConfig, GlobalManager } from '../global/GlobalManager';
import { CommonUtils } from '../utils/CommonUtils';

export class SceneManager {
    private static _instance: SceneManager;
    public static get instance(): SceneManager {
        if (!this._instance) {
            this._instance = new SceneManager();
        }
        return this._instance;
    }

    // 缓存已加载的bundle，避免重复加载
    private bundleCache: Map<string, any> = new Map();

    private constructor() {}

    /**
     * 加载场景
     */
    public async loadScene(config: SceneConfig, onLaunched?: () => void) {
        if (config.type === 'bundle' && config.bundle) {
            const bundle = await this.getOrLoadBundle(config);
            bundle.loadScene(config.name, () => {
                CommonUtils.cleanupBeforeScene();
                onLaunched && onLaunched();
            });
        } else {
            director.loadScene(config.name, () => {
                CommonUtils.cleanupBeforeScene();
                onLaunched && onLaunched();
            });
        }
    }

    /**
     * 根据场景配置预加载场景，支持远程 bundle（serverUrl）
     */
    public async preloadScene(sceneCfg: SceneConfig): Promise<void> {
        if (sceneCfg.type === 'bundle' && sceneCfg.bundle) {
            // 预加载分包场景，支持 serverUrl
            const bundle = await this.getOrLoadBundle(sceneCfg);
            await new Promise<void>((resolve, reject) => {
                bundle.preloadScene(sceneCfg.name, (err) => {
                    if (err) reject(err);
                    else resolve();
                });
            });
        } else {
            // 预加载主包场景
            await new Promise<void>((resolve, reject) => {
                director.preloadScene(sceneCfg.name, (err) => {
                    if (err) reject(err);
                    else resolve();
                });
            });
        }
    }

    /**
     * 获取或加载bundle，支持缓存
     */
    private async getOrLoadBundle(config: SceneConfig): Promise<any> {
        // 检查是否应该使用远程加载
        const shouldUseRemote = GlobalManager.shouldUseRemote(config.isRemote || false, true);
        
        const bundleKey = shouldUseRemote ? 
            GlobalManager.getRemoteCacheKey(config.bundle!, true) : 
            config.bundle!;

        // 检查缓存
        if (this.bundleCache.has(bundleKey)) {
            return this.bundleCache.get(bundleKey);
        }

        // 加载bundle
        let bundle;
        if (shouldUseRemote) {
            // 远程bundle需要加版本号目录
            const bundleUrl = GlobalManager.getRemoteBundleUrl(config.bundle!);
            console.log(`[SceneManager] 加载远程bundle: ${bundleUrl}`);
            bundle = await BundleManager.instance.loadBundle(bundleUrl);
        } else {
            // 本地bundle或H5环境下强制使用本地
            console.log(`[SceneManager] 加载本地bundle: ${config.bundle}`);
            bundle = await BundleManager.instance.loadBundle(config.bundle!);
        }

        // 缓存bundle
        this.bundleCache.set(bundleKey, bundle);
        return bundle;
    }

    /**
     * 清理bundle缓存
     */
    public clearBundleCache(): void {
        this.bundleCache.clear();
    }

    /**
     * 移除指定的bundle缓存
     */
    public removeBundleCache(bundleName: string, isRemote: boolean = false): void {
        const bundleKey = isRemote ? 
            GlobalManager.getRemoteCacheKey(bundleName, true) : 
            bundleName;
        this.bundleCache.delete(bundleKey);
    }

    /**
     * 获取缓存的bundle数量
     */
    public getBundleCacheSize(): number {
        return this.bundleCache.size;
    }

    /**
     * 获取当前场景名称
     */
    public getCurrentSceneName(): string {
        return director.getScene().name;
    }

    /**
     * 检查场景是否已预加载
     */
    public isScenePreloaded(sceneName: string): boolean {
        // 检查主包场景是否已预加载
        // 注意：Cocos Creator 3.x 没有直接的 isSceneLoaded 方法
        // 这里可以通过检查 bundle 缓存来间接判断
        return this.bundleCache.has(sceneName);
    }

    /**
     * 获取缓存信息
     */
    public getCacheInfo(): { bundleCount: number; cachedBundles: string[] } {
        return {
            bundleCount: this.bundleCache.size,
            cachedBundles: Array.from(this.bundleCache.keys())
        };
    }

    /**
     * 销毁实例（用于测试或重置）
     */
    public static destroy(): void {
        if (this._instance) {
            this._instance.clearBundleCache();
            this._instance = null!;
        }
    }
} 